# -*- coding: utf-8 -*-

################################################################################
## Form generated from reading UI file 'SYSTEM_PYSIDE6_FILE_LOCATOR_1_0FmCIhY.ui'
##
## Created by: Qt User Interface Compiler version 6.9.1
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################

from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
    QMetaObject, QObject, QPoint, QRect,
    QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
    QFont, QFontDatabase, QGradient, QIcon,
    QImage, QKeySequence, QLinearGradient, QPainter,
    QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QComboBox, QDialog, QGroupBox,
    QLabel, QLineEdit, QListView, QPushButton,
    QSizePolicy, QWidget)

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        if not Dialog.objectName():
            Dialog.setObjectName(u"Dialog")
        Dialog.resize(621, 571)
        Dialog.setMinimumSize(QSize(621, 571))
        Dialog.setMaximumSize(QSize(621, 571))
        self.groupBox = QGroupBox(Dialog)
        self.groupBox.setObjectName(u"groupBox")
        self.groupBox.setGeometry(QRect(10, 10, 601, 551))
        self.listView = QListView(self.groupBox)
        self.listView.setObjectName(u"listView")
        self.listView.setGeometry(QRect(10, 110, 581, 311))
        self.pushButton_1 = QPushButton(self.groupBox)
        self.pushButton_1.setObjectName(u"pushButton_1")
        self.pushButton_1.setGeometry(QRect(40, 30, 91, 31))
        self.pushButton_2 = QPushButton(self.groupBox)
        self.pushButton_2.setObjectName(u"pushButton_2")
        self.pushButton_2.setGeometry(QRect(140, 30, 91, 31))
        self.lineEdit_1 = QLineEdit(self.groupBox)
        self.lineEdit_1.setObjectName(u"lineEdit_1")
        self.lineEdit_1.setGeometry(QRect(70, 430, 521, 31))
        self.label_1 = QLabel(self.groupBox)
        self.label_1.setObjectName(u"label_1")
        self.label_1.setGeometry(QRect(10, 430, 61, 31))
        self.label_1.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.label_2 = QLabel(self.groupBox)
        self.label_2.setObjectName(u"label_2")
        self.label_2.setGeometry(QRect(10, 470, 61, 31))
        self.label_2.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.comboBox_1 = QComboBox(self.groupBox)
        self.comboBox_1.addItem("")
        self.comboBox_1.setObjectName(u"comboBox_1")
        self.comboBox_1.setGeometry(QRect(70, 470, 521, 31))
        self.lineEdit_2 = QLineEdit(self.groupBox)
        self.lineEdit_2.setObjectName(u"lineEdit_2")
        self.lineEdit_2.setGeometry(QRect(70, 70, 391, 31))
        self.label_3 = QLabel(self.groupBox)
        self.label_3.setObjectName(u"label_3")
        self.label_3.setGeometry(QRect(10, 70, 61, 31))
        self.label_3.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.pushButton_4 = QPushButton(self.groupBox)
        self.pushButton_4.setObjectName(u"pushButton_4")
        self.pushButton_4.setGeometry(QRect(500, 70, 91, 31))
        self.iconButton_2 = QPushButton(self.groupBox)
        self.iconButton_2.setObjectName(u"iconButton_2")
        self.iconButton_2.setGeometry(QRect(230, 30, 31, 31))
        self.iconButton_1 = QPushButton(self.groupBox)
        self.iconButton_1.setObjectName(u"iconButton_1")
        self.iconButton_1.setGeometry(QRect(10, 30, 31, 31))
        self.iconButton_3 = QPushButton(self.groupBox)
        self.iconButton_3.setObjectName(u"iconButton_3")
        self.iconButton_3.setGeometry(QRect(470, 70, 31, 31))
        self.pushButton_5 = QPushButton(self.groupBox)
        self.pushButton_5.setObjectName(u"pushButton_5")
        self.pushButton_5.setGeometry(QRect(500, 510, 91, 31))
        self.pushButton_3 = QPushButton(self.groupBox)
        self.pushButton_3.setObjectName(u"pushButton_3")
        self.pushButton_3.setGeometry(QRect(400, 510, 91, 31))

        self.retranslateUi(Dialog)

        QMetaObject.connectSlotsByName(Dialog)
    # setupUi

    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(QCoreApplication.translate("Dialog", u"Dialog", None))
        self.groupBox.setTitle(QCoreApplication.translate("Dialog", u"GroupBox", None))
        self.pushButton_1.setText(QCoreApplication.translate("Dialog", u"Backward", None))
        self.pushButton_2.setText(QCoreApplication.translate("Dialog", u"Forward", None))
        self.label_1.setText(QCoreApplication.translate("Dialog", u"\u6587\u4ef6\u540d", None))
        self.label_2.setText(QCoreApplication.translate("Dialog", u"\u6269\u5c55\u540d", None))
        self.comboBox_1.setItemText(0, QCoreApplication.translate("Dialog", u".xlsx (Microsoft Office Excel 2007-2010)", None))

        self.label_3.setText(QCoreApplication.translate("Dialog", u"Path", None))
        self.pushButton_4.setText(QCoreApplication.translate("Dialog", u"\u8f6c\u5230", None))
        self.iconButton_2.setText("")
        self.iconButton_1.setText("")
        self.iconButton_3.setText("")
        self.pushButton_5.setText(QCoreApplication.translate("Dialog", u"Confirm", None))
        self.pushButton_3.setText(QCoreApplication.translate("Dialog", u"Select", None))
    # retranslateUi

# #############################################################################################
# 新增 PyQt / PySide 对话框类 Class (继承自 QDialog) 以使用 Qt Designer / PySide 生成的 UI 代码
# #############################################################################################

import os
import sys
# ..................................................
from PySide6.QtCore import Qt
from PySide6.QtCore import QStringListModel    # 用于生成文本形式列表
from PySide6.QtGui  import QStandardItemModel  # 用于生成标准形式列表
from PySide6.QtGui  import QStandardItem, QIcon, QPixmap  # 用于对标准形式列表项配置细节

class Dialog_System_File_Locator(QDialog):

    # PyQt / PySide 对话框类 Class (继承自 QDialog)

    def __init__(self, parent = None):

        super().__init__(parent)
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)

        # 设置 QListView 选择模式
        self.ui.listView.setSelectionMode(QListView.SingleSelection)    # 单选
    #   self.ui.listView.setSelectionMode(QListView.MultiSelection)     # 多选
    #   self.ui.listView.setSelectionMode(QListView.ExtendedSelection)  # 扩展选择

        # 设置 Icon 图标
        self.ui.iconButton_1.setIcon(QPixmap("./icon-arrow-left.svg"))
        self.ui.iconButton_2.setIcon(QPixmap("./icon-arrow-right.svg"))
        self.ui.iconButton_3.setIcon(QPixmap("./icon-rotate-counterclockwise.svg"))
    #   self.ui.iconButton_3.setIcon(QIcon())      # 清除 Icon (方法 1)
    #   self.ui.iconButton_3.setIcon(QIcon(None))  # 清除 Icon (方法 2)

        self.PUB_Current_Path = os.getcwd()  # 获取当前工作路径
        self.PUB_Model_for_QListView = None
        # ..........................................
        self.for_QListView_setModel(Current_Path = self.PUB_Current_Path)
        # ..........................................
        self.PUB_Located_Work_Path = "unknown"
        self.PUB_Inputed_File_Name = "unknown"
        self.PUB_Changed_File_Ext  = "unknown"
        self.PUB_Compose_Full_Path = "unknown"

        # 连接信号和槽
        self.setup_connections()

    def setup_connections(self):

        """ 连接所有信号和槽 """

        # 连接按钮
        self.ui.listView.doubleClicked.connect(self.for_QListView_item_doubleClicked)
        self.ui.pushButton_1.clicked.connect(self.on_pushButton_1_clicked) # "向后 (Backward)" 按键
        self.ui.iconButton_1.clicked.connect(self.on_pushButton_1_clicked) # "向后 (Backward)" 图标
        self.ui.pushButton_2.clicked.connect(self.on_pushButton_2_clicked) # "向前 (Forward)" 按键
        self.ui.iconButton_2.clicked.connect(self.on_pushButton_2_clicked) # "向前 (Forward)" 图标
        self.ui.pushButton_3.clicked.connect(self.on_pushButton_3_clicked) # "选择 (Select)" 按键
        self.ui.pushButton_5.clicked.connect(self.on_pushButton_5_clicked) # "确认 (Confirm)" 按键

    def keyPressEvent(self, event):

        """ 处理键盘按下事件 """

        key      = event.key()
        modifier = event.modifiers() # 判断修饰键
        # ..........................................
        # 处理特定按键
        if (key == Qt.Key.Key_Escape   ): self.close()  # 关闭窗口 (Esc)
        if (key == Qt.Key.Key_Backspace): self.on_pushButton_1_clicked()
        # ..........................................
        # 处理组合按键
        if (modifier == Qt.KeyboardModifier.ControlModifier):
            if (key == Qt.Key.Key_Enter ): self.on_pushButton_5_clicked()  # Ctrl + Enter
            if (key == Qt.Key.Key_Return): self.on_pushButton_5_clicked()  # Ctrl + Enter
        # ..........................................
        # 让文本编辑器正常处理文本输入 (其他按键交给父类处理)
        super().keyPressEvent(event)

    def DIY_Get_OSPath_Type(self, OSPath:str) -> str:

        OSPath_Type:str = "null"
        # ..........................................
        if (os.path.isfile(OSPath) == True):
            OSPath_Type = "file"
        # ..........................................
        if (os.path.isdir(OSPath) == True):
            OSPath_Type = "directory"
        # ..........................................
        return OSPath_Type

    def DIY_Get_Folder_Icon(self):

        """ 获取文件夹图标 """

        folder_icon = QIcon.fromTheme("folder")  # 尝试使用系统主题文件夹图标
        # ..........................................
        # 如果指定的主题图标不可用则使用主题默认图标
        if (folder_icon.isNull() == True): folder_icon = QIcon.fromTheme("inode-directory")
        # ..........................................
        return folder_icon

    def DIY_Get_File_Icon(self, File_Name:str):

        """ 根据文件类型获取图标 """

        # 根据文件扩展名选择图标
        ext = os.path.splitext(File_Name)[1].lower()
        # ..........................................
        # 定义文件类型对应的图标
        icon_map = {
            ".txt":  "text-plain",
            ".pdf":  "application-pdf",
            ".jpg":  "image-jpeg",
            ".jpeg": "image-jpeg",
            ".png":  "image-png",
            ".gif":  "image-gif",
            ".mp3":  "audio-mpeg",
            ".mp4":  "video-mp4",
            ".zip":  "application-zip",
            ".py":   "text-x-python",
            ".html": "text-html",
            ".css":  "text-css",
            ".js":   "text-x-javascript",
            "主题默认图标": "text-x-generic"
        }
        # ..........................................
        icon_name = icon_map.get(ext, "text-x-generic")  # 尝试获取系统主题对应的图标名称
        file_icon = QIcon.fromTheme(icon_name)           # 尝试使用系统主题对应的图标
        # ..........................................
        # 如果指定的主题图标不可用则使用本地 SVG 图标
        if (file_icon.isNull() == True): file_icon = QIcon("./icon-file.svg")
        # ..........................................
        return file_icon

    def for_QListView_setModel(self, Current_Path:str = "./") -> int:

        # 替换多个 '/' 如 "//" 替换为 '/'
        Updated_Current_Path = Current_Path.replace(f"{os.sep}{os.sep}", f"{os.sep}")
        # 将 "相对路径" 转换为 "绝对路径" (要求起始路径必须明确, 如 D: 或 /home)
        Updated_Current_Path = os.path.normpath(Updated_Current_Path)

    #   # --------------------------------------
    #   # 使用 QStringListModel 创建文本形式列表
    #   # --------------------------------------
    #
    #   Model = QStringListModel()  # 创建 QStringListModel
    #
    #   # 将 Python 字符串列表转换为 Qt 可接受的格式
    #   # 在 PySide6 中, 可以直接传递 Python 列表
    #   Model.setStringList(["example", "example.csv", ...])

        # ----------------------------------------
        # 使用 QStandardItemModel 创建标准形式列表
        # ----------------------------------------

        Model = QStandardItemModel()  # 创建 QStandardItemModel

    #   Model.clear()  # 清空当前模型

        # 为 "当前路径 (Path) 的子项 (Sub-Item)" 配置细节
        for Sub_Item in os.listdir(Updated_Current_Path):
            Full_Path:str      = os.path.join(Updated_Current_Path, Sub_Item)
            Full_Path_Type:str = self.DIY_Get_OSPath_Type(OSPath = Full_Path)
            # ......................................
            if (Full_Path_Type == "directory"):
                Item = QStandardItem(self.DIY_Get_Folder_Icon(), Sub_Item)  # 配置文件夹图标
                Item.setToolTip(f"目录: {Sub_Item}")  # 配置工具提示
                Model.appendRow(Item)
            # ......................................
            if (Full_Path_Type == "file"):
                Item = QStandardItem(self.DIY_Get_File_Icon(Sub_Item), Sub_Item)  # 配置文件图标
                Item.setToolTip(f"文件: {Sub_Item}")  # 配置工具提示
                Model.appendRow(Item)

        # 将模型设置到 ListView
        self.ui.listView.setModel(Model)

        # 将 Path 传递到公共变量, 以便其它函数调用
        self.PUB_Current_Path = Updated_Current_Path
        # 将 Model 传递到公共变量, 以便其它函数调用
        self.PUB_Model_for_QListView = Model

        # -----------------------------------------------------------------------------
        # 如果存在 "地址栏" 则将当前目录地址更新到 "地址栏" (通常位于顶部且名称为 Path)
        # -----------------------------------------------------------------------------

        self.ui.lineEdit_2.setText(Updated_Current_Path)

        return 1

    def for_QListView_getSelectedTexts(self):

        LIST_Selected_Indexes:list = self.ui.listView.selectedIndexes()
        # >>> print(LIST_Selected_Indexes)
        # [<PySide6.QtCore.QModelIndex(0,0,0x292ba276430,QStandardItemModel(0x292b8237ed0)) at 0x00000292BA739480>]
        # ..........................................
        # 提取 self.ui.listView.selectedIndexes() 的行号 (整数)
        LIST_Selected_Row_Num:list = [Index.row() for Index in LIST_Selected_Indexes]
        # >>> print(LIST_Selected_Row_Num)
        # [0]
        # ..........................................
        LIST_Selected_Items:list = [self.PUB_Model_for_QListView.item(i) for i in LIST_Selected_Row_Num]
        # >>> Model = QStandardItemModel()
        # >>> Item = QStandardItem(QIcon(None), "example_text")
        # >>> Model.appendRow(Item)
        # >>> print(Model.item(0))
        # <PySide6.QtGui.QStandardItem object at 0x000001DCCC638580>
        LIST_Selected_Texts:list = [Item.text() for Item in LIST_Selected_Items]
        # ..........................................
        return LIST_Selected_Texts

    def for_QListView_item_doubleClicked(self):

        self.on_pushButton_3_clicked()
        # ..........................................
        return 1

    def on_pushButton_1_clicked(self):  # "向后 (Backward)" 按键

        Updated_Current_Path = self.PUB_Current_Path + os.sep + ".."
        # ..........................................
        self.for_QListView_setModel(Current_Path = Updated_Current_Path)

    def on_pushButton_2_clicked(self):  # "向前 (Forward)" 按键

        LIST_Selected_Texts:list = self.for_QListView_getSelectedTexts()
        # ..........................................
        if (LIST_Selected_Texts != []):
            Selected_Path:str      = self.PUB_Current_Path + os.sep + LIST_Selected_Texts[0]
            Selected_Path_Type:str = self.DIY_Get_OSPath_Type(OSPath = Selected_Path)
            # ......................................
            if (Selected_Path_Type == "directory"):
                self.for_QListView_setModel(Current_Path = Selected_Path)
        # ..........................................
        return 1

    def on_pushButton_3_clicked(self):  # "选择 (Select)" 按键

        LIST_Selected_Texts:list = self.for_QListView_getSelectedTexts()
        # ..........................................
        if (LIST_Selected_Texts != []):
            Selected_Path:str      = self.PUB_Current_Path + os.sep + LIST_Selected_Texts[0]
            Selected_Path_Type:str = self.DIY_Get_OSPath_Type(OSPath = Selected_Path)
            # ......................................
            if (Selected_Path_Type == "directory"):
                self.for_QListView_setModel(Current_Path = Selected_Path)
            # ......................................
            if (Selected_Path_Type == "file"):
                self.ui.lineEdit_1.setText(LIST_Selected_Texts[0])
        # ..........................................
        return 1

    def on_pushButton_5_clicked(self):  # "确认 (Confirm)" 按键

        self.PUB_Located_Work_Path = self.ui.lineEdit_2.text()
        self.PUB_Inputed_File_Name = self.ui.lineEdit_1.text()
        self.PUB_Changed_File_Ext  = self.ui.comboBox_1.currentText()
        # ..........................................
        self.PUB_Changed_File_Ext  = ".xlsx" if (".xlsx" in self.PUB_Changed_File_Ext[0:5]) else "unknown"
        self.PUB_Compose_Full_Path = self.PUB_Located_Work_Path + os.sep + \
                                     self.PUB_Inputed_File_Name + \
                                     self.PUB_Changed_File_Ext
        self.PUB_Compose_Full_Path = self.PUB_Compose_Full_Path.replace(f"{os.sep}{os.sep}", f"{os.sep}")
        # ..........................................
    #   self.close()  # 只关闭当前窗口
    #   self.quit()   # 完全退出程序
    #   self.exit()   # 完全退出程序 (返回退出代码)
        # ..........................................
        self.accept() # 关闭对话框并返回结果 (主要用于 QDialog 对话框, 设置对话框结果为 Accepted)
    #   self.reject() # 关闭对话框并返回结果 (主要用于 QDialog 对话框, 设置对话框结果为 Rejected)
        # ..........................................
        # self.accept() / self.reject() 窗口调用示例:
        # >>> new_window = Dialog_File_Browser()
        # >>>
        # >>> window_res = new_window.exec()
        # >>> if (window_res == QDialog.DialogCode.Accepted):
        # ...     print(new_window.Compose_Full_Path)
        # 'C:\Example\Sales.xlsx'
        # >>>
        # >>> # 注意: 用户点击窗口关闭按钮通常也会触发 Rejected
        # >>> # Tips: new_window.exec(): 模态 (Modal) 对话框, 阻塞线程到用户响应后返回 DialogCode
        # >>> # Tips: new_window.show(): 非模态 (Modeless) 窗口, 非阻塞, 执行结束立即关闭 (关闭较快, 用户不易操作, 类似闪退)

if __name__ == "__main__":

    app = QApplication(sys.argv)

    # 设置应用程序样式
    app.setStyle('Fusion')

    # 创建并显示对话框
    dialog = Dialog_System_File_Locator()
    dialog.show()

    sys.exit(app.exec())
